# -*- coding:utf-8 -*-
"""
book表实现增删改查
"""
import logging
import random

import pymongo

from LibrarySystem.config.config import Config
from LibrarySystem.repositories.mongodb.interface.book_data_interface import BookDataInterface
from LibrarySystem.repositories.mongodb.models.book_models import Book

module_logger = logging.getLogger("logger")


class BookRepository(BookDataInterface):
    """
    @ClassName：BookRepository
    @Description： 继承图书数据层接口类
    负责实现接口功能
    @Author：锦沐Python
    """
    def __init__(self):
        self.config = Config()
        self.connection = None
        self.cursor = None
        # 连接到 MongoDB 服务器
        client = pymongo.MongoClient(host=self.config.MONGODB_CONFIG["host"],
                                     port=self.config.MONGODB_CONFIG["port"])
        # 选择数据库
        db = client.get_database(self.config.MONGODB_CONFIG["database_name"])
        self.books_collection = db.get_collection(self.config.MONGODB_CONFIG["books_collection"])

    def add_book(self, book: Book):
        """
        添加书籍
        :param book:
        :return:
        """
        book_id = book.book_id
        try:
            result = self.books_collection.find_one(filter={"book_id": book_id}, projection={"_id":0})

            if  result:
                module_logger.info("books 已存在")
                return (False, f"books {book_id} 已存在")

            # 写入数据
            result = self.books_collection.insert_one(document=book.obj_to_dict())

            if result:
                return (True, f"books {book_id} 添加成功")
            else:
                module_logger.info(f"添加书籍失败")
                return (False, f"添加书籍失败")

        except Exception as e:
            # 处理其他可能的异常
            module_logger.info(f"添加书籍失败：{e}")
            return (False, f"添加书籍失败：{e}")

    def update_book(self, book: Book):
        """
        根据book_id更新书籍信息
        :param book:
        :return:
        """
        book_id = book.book_id

        try:
            # 读数据
            result = self.books_collection.find_one(filter={"book_id": book_id}, projection={"_id":0})

            if result is None:
                module_logger.info(f"书籍{book_id}不存在，更新失败")
                return (False, f"书籍{book_id}不存在，更新失败")

            # 写入数据
            result = self.books_collection.update_one(filter={"book_id":book_id}, update={"$set": book.obj_to_dict()})

            if result.matched_count > 0:
                module_logger.info(f"书籍{book_id} 更新成功")
                return (True, f"书籍{book_id} 更新成功")
            else:
                module_logger.error(f"更新失败 {book_id}")
                return (False, f"更新失败 {book_id}")

        except Exception as e:
            # 处理其他可能的异常
            module_logger.info(f"修改书籍信息失败：{e}")
            return (False, f"修改书籍信息失败：{e}")

    def query_book(self, book_id: str):
        """
            查询书籍
            :param book_id:
            :return:
        """
        try:
            # 读数据
            result = self.books_collection.find_one(filter={"book_id": book_id}, projection={"_id":0})

            if result is None:
                module_logger.info(f"书籍{book_id}不存在，查询失败")
                return (False, f"书籍{book_id}不存在，查询失败")

            # 创建一个 Book 对象 解决异常：tuple index out of range

            if result:
                get_book = Book(**result)
                return (True, get_book)
            else:
                module_logger.info(f"书籍{book_id}不存在，查询失败")
                return (False, f"书籍{book_id}不存在，查询失败")

        except Exception as e:
            # 处理其他可能的异常
            module_logger.info(f"查询书籍信息失败：{e}")
            return (False, f"查询书籍信息失败：{e}")

    def del_book(self, book_id: str):
        """
        删除书籍
        :param book_id:
        :return:
        """
        try:
            # 读数据
            result = self.books_collection.find_one(filter={"book_id": book_id}, projection={"_id":0})

            if result is None:
                module_logger.info(f"书籍{book_id}不存在，删除失败")
                return (False, f"书籍{book_id}不存在，删除失败")

            # 写入数据
            result = self.books_collection.delete_one(filter={"book_id": book_id})
            if result.deleted_count > 0:
                return (True, f"书籍{book_id} 删除成功")
            else:
                return (False, f"删除书籍信息失败")

        except Exception as e:
            # 处理其他可能的异常
            module_logger.info(f"删除书籍信息失败：{e}")
            return (False, f"删除书籍信息失败：{e}")

    def get_books(self, count: int):
        """
        :param count:  小于 0 表示获取全部
        :return:
        """
        book_list = []
        try:
            # 读取数据
            if count <= 0:
                # 查询所有书籍
                results = self.books_collection.find({}, {"_id":0})
            else:
                # 限制查询数量
                results = self.books_collection.find({}, {"_id":0}).limit(count)

            for book_data in results:
                book_list.append(Book(**book_data))

            # 顺序打乱，制造随机性展示
            random.shuffle(book_list)

            return (True, book_list)
        except Exception as e:
            module_logger.info(f"获取书籍失败: {e}")
            return (False, f"获取书籍失败：{e}")

    def get_books_by_keywords(self, fields_to_check:list, keywords:str):

        query_filters = []
        book_list = []

        # 构造查询条件
        for field in fields_to_check:
            query_filters.append({field: {"$regex": f".*{keywords}.*", "$options": "i"}})

        try:
            # 查询数据库
            results = self.books_collection.find({"$or": query_filters}, {"_id":0})
            if results:
                for book_data in results:
                    book_list.append(Book(**book_data))

            # 顺序打乱，制造随机性展示
            random.shuffle(book_list)
            return (True, book_list)
        except Exception as e:
            module_logger.error(f"根据关键词获取书籍错误：{e}")
            return (False, f"根据关键词获取书籍错误：{e}")

    def get_books_by_column(self, column: str, value:str):
        # 构造 SQL 查询语句

        book_list = []

        try:
            # 查询数据库
            results = self.books_collection.find({column: value}, {"_id":0})
            if results:
                for book_data in results:
                    book_list.append(Book(**book_data))

                # 顺序打乱，制造随机性展示
                random.shuffle(book_list)
                return (True, book_list)

        except Exception as e:
            module_logger.error(f"根据列名获取书籍错误：{e}")
            return (False, f"根据列名获取书籍错误：{e}")

